package com.myblog.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.myblog.common.lang.Result;

import com.myblog.entity.User;
import com.myblog.service.UserService;
import com.myblog.shiro.JwtToken;
import com.myblog.util.JwtUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
public class AccountController {

    @Autowired
    UserService userService;

    @Autowired
    JwtUtils jwtUtils;


    @PostMapping("/login")
    public Result login(@RequestBody User loginUser, HttpServletResponse response) {

        User user = userService.getOne(new QueryWrapper<User>().eq("username", loginUser.getUsername()));

        //Assert.notNull(user, "用户不存在");  //这种方式，前端会报红，后端会抛出断言的异常，但就是不返回 Result.fail ? why ?
        if(user == null){
            return Result.fail("用户名不存在！~");
        }

        System.out.println("用户已找到，即将匹配密码");
        //匹配密码
        String nowPwd = new SimpleHash("md5",loginUser.getPassword(),user.getSalt(),3).toString();
        String rightPwd = user.getPassword();

        if(!rightPwd.equals(nowPwd)){
            return Result.fail("密码不正确",loginUser);
        }

        //生成 token
        String jwt = jwtUtils.generateToken(user.getId());

        response.setHeader("Authorization", jwt);
        response.setHeader("Access-control-Expose-Headers", "Authorization");

        /* 记住，导入的二者，都是 shiro 包下的 */
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.login(new JwtToken(jwt));   //进行 Shiro 登陆验证

        System.out.println(currentUser.isAuthenticated());


        //更新登陆地点信息
        user.setLoginProvince(loginUser.getLoginProvince());
        user.setLoginCity(loginUser.getLoginCity());
        user.setLoginLat(loginUser.getLoginLat());
        user.setLoginLng(loginUser.getLoginLng());
        userService.saveOrUpdate(user);


        //user密码保护
        user.toProtected();
        return Result.succ(MapUtil.builder()
                .put("user",user)
                .put("token",jwt)
                .map()
        );
    }



    /* 没进行验证的话，就不能注销，该方法会报错 */
    @RequiresAuthentication
    @GetMapping("/logout")
    public Result logout() {
        /* shiro 的注销请求 */
        SecurityUtils.getSubject().logout();
        System.out.println("进入注销请求！-------------------------");
        return Result.succ(null);
    }

}
